package com.example.dangerouscargodriver.controller;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Message;
import android.util.Log;

import com.baiju.netmanager.Http.HttpRequest;
import com.baiju.netmanager.Http.IHttpRequest;
import com.baiju.netmanager.Http.INetResponse;
import com.example.dangerouscargodriver.DangerousCargoDriverApplication;
import com.example.dangerouscargodriver.entry.CityInfo;
import com.example.dangerouscargodriver.entry.DistrictInfo;
import com.example.dangerouscargodriver.entry.ProvinceInfo;
import com.example.dangerouscargodriver.event.Event;
import com.example.dangerouscargodriver.event.LoadHttpResourceStatus;
import com.example.dangerouscargodriver.module.ResponseInfo;
import com.example.dangerouscargodriver.param.RemoteAPI;
import com.example.dangerouscargodriver.param.RemoteAPICmd;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.reflect.TypeToken;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class AreaInfoController extends Controller{

    public static final int EVENT_AREA_LOADING = 0;
    public static final int EVENT_AREA_LOAD_DONE = 1;

    private static final  int MSG_ADD_LISTENER = 0;
    private static final  int MSG_LOAD_AREA_ATTR = 1;
    private static final String TAG = "AreaInfoController";

    private static AreaInfoController mInstance = null;
    private int mLoadAreaInfoStatus = EVENT_AREA_LOADING;

    private List<ProvinceInfo> mAreaArray = null;
    private int mLoadProvinceInfoNum = 0;
    private int mLoadCityInfoNum = 0;
    private int mLoadDistrictInfoNum = 0;

    private HttpRequest mHttp = null;
    private HttpResponseListener mHttpListener = null;
    private HashMap<java.lang.Class, IControllerEventListener> mControllerListener = null;

    public static AreaInfoController Instance(){
        if(mInstance == null){
            mInstance = new AreaInfoController(DangerousCargoDriverApplication.getAppContext());
        }

        return mInstance;
    }

    public AreaInfoController(Context context){
        mControllerListener = new HashMap<>();
        mAreaArray = new ArrayList<>();
        mHttpListener = new HttpResponseListener();
        mHttp = HttpRequest.Instance(context);
        mHttp.attachResponseListener(mHttpListener, AreaInfoController.class);
        mHttp.startUp();

        SharedPreferences sharedPreferences =
                DangerousCargoDriverApplication.getAppContext().getSharedPreferences(
                        "wsj_area",
                        Context.MODE_PRIVATE);
        String areaInfo = sharedPreferences.getString("area", "");
        if(areaInfo != null && !areaInfo.equals("")){
            Gson gson = new Gson();
            Type type = new TypeToken<List<ProvinceInfo>>() {}.getType();
            mAreaArray =  gson.fromJson(areaInfo, type);
            mLoadAreaInfoStatus = EVENT_AREA_LOAD_DONE;
        }
        else {
            loadAreaInfo();
        }
    }

    public boolean attachControllerListener(java.lang.Class object, IControllerEventListener listener){
        if(mControllerListener.containsKey(object)){
            return false;
        }
        else {
            mControllerListener.put(object, listener);
            Message msg = new Message();
            msg.what = MSG_ADD_LISTENER;
            msg.obj = object;
            sendMessage(msg);
            return true;
        }
    }

    public boolean unAttachControllerListener(java.lang.Class object, IControllerEventListener listener){
        if(mControllerListener.containsKey(object) && mControllerListener.get(object) == listener){
            mControllerListener.remove(object);
            return true;
        }
        else {
            return false;
        }
    }

    public void registerListener(INetResponse listener, Class object){
        mHttp.attachResponseListener(listener, object);
    }

    @Override
    protected void handleControllerMessage(Message msg){
        switch (msg.what){
            case MSG_ADD_LISTENER:
                LoadHttpResourceStatus status = new LoadHttpResourceStatus();
                status.setWhat(mLoadAreaInfoStatus);
                mControllerListener.get(msg.obj).onEvent(Event.EVENT_LOAD_HTTP_RESOURCE_AREA, status.toJson());
                break;
            case MSG_LOAD_AREA_ATTR:
                mAreaArray.clear();
                mLoadAreaInfoStatus = EVENT_AREA_LOADING;
                loadAreaInfo();
            default:
                break;
        }
    }

    public void loadAreaInfo(){
        HashMap<String, String> header = new HashMap<String, String>();
        header.put("app-type", "Android");

        HashMap<String, String> match_param = new HashMap<String, String>();
        match_param.put("pid", Integer.toString(1));

        mHttp.sendRequest(
                IHttpRequest.RequestMethod.GET_METHOD,
                RemoteAPI.REQUEST_V1_HOME_AREA_DATA,
                header,
                match_param,
                RemoteAPICmd.REQUEST_V1_HOME_AREA_DATA_PROVINCE,
                AreaInfoController.class);
    }

    public List<ProvinceInfo> getProvinceInfo(){
        return mAreaArray;
    }

    public List<CityInfo> getCityInfo(String province){
        for(int index = 0; index < mAreaArray.size(); index++){
            if(mAreaArray.get(index).getId().equals(province)){
                return mAreaArray.get(index).getCity();
            }
        }

        return null;
    }

    public List<DistrictInfo> getDistrictInfo(String province, String city){
        for(int index = 0; index < mAreaArray.size(); index++){
            if(mAreaArray.get(index).getId().equals(province)){
                List<CityInfo> cityInfos = mAreaArray.get(index).getCity();
                for(int index2 = 0; index2 < cityInfos.size(); index2++){
                    if(cityInfos.get(index2).getExtra().getCity().getId().equals(city)){
                        return cityInfos.get(index2).getDistrict();
                    }
                }
            }
        }

        return null;
    }

    private class HttpResponseListener implements INetResponse {

        private static final String TAG = "HttpResponseListener";

        @Override
        public void onResponse(int actionId, String response) {
            try {
                JSONObject res = new JSONObject(response);
                Gson gson = new Gson();

                if(actionId == RemoteAPICmd.REQUEST_V1_HOME_AREA_DATA_PROVINCE){
                    //Log.d(TAG, "onResponse: " + response);
                    ResponseInfo responseInfo = gson.fromJson(response, ResponseInfo.class);
                    if(responseInfo != null && responseInfo.getStatus() == 1) {
                        if (res.getJSONObject("data").has("area_data")) {
                            JSONArray data = res.getJSONObject("data").getJSONArray("area_data");
                            Type type = new TypeToken<List<ProvinceInfo>>() {
                            }.getType();
                            mAreaArray = gson.fromJson(data.toString(), type);
                            for (int index = 0; index < mAreaArray.size(); index++) {

                                HashMap<String, String> match_param = new HashMap<String, String>();
                                match_param.put("keyword", mAreaArray.get(index).getName());
                                match_param.put("level", "city");

                                mHttp.sendRequest(
                                        IHttpRequest.RequestMethod.GET_METHOD,
                                        RemoteAPI.REQUEST_V1_HOME_AREA_DATA,
                                        null,
                                        match_param,
                                        RemoteAPICmd.REQUEST_V1_HOME_AREA_DATA_CITY,
                                        AreaInfoController.class);
                            }
                        }
                        else {
                            //返回成功，但却没有数据,此种情况暂不处理
                        }
                    }
                    else{
                        //返回异常
                        Message message = new Message();
                        message.what = MSG_LOAD_AREA_ATTR;
                        sendMessageDelayed(message, 1000);
                    }
                }
                else if(actionId == RemoteAPICmd.REQUEST_V1_HOME_AREA_DATA_CITY){
                    //Log.d(TAG, "onResponse: " + response);
                    ResponseInfo responseInfo = gson.fromJson(response, ResponseInfo.class);
                    if(responseInfo != null && responseInfo.getStatus() == 1) {
                        mLoadCityInfoNum += 1;
                        if (res.getJSONObject("data").has("area_data")) {
                            JSONArray data = res.getJSONObject("data").getJSONArray("area_data");
                            Type type = new TypeToken<List<CityInfo>>() {
                            }.getType();
                            List<CityInfo> city = gson.fromJson(data.toString(), type);
                            for (int index = 0; index < mAreaArray.size(); index++) {
                                if (mAreaArray.get(index).getId().equals(city.get(0).getExtra().getProvince().getId())) {
                                    mAreaArray.get(index).setCity(city);
                                    break;
                                }
                            }
                        } else {

                        }

                        //当加载完城市信息之后，开始加载区级信息
                        if (mLoadCityInfoNum == mAreaArray.size()) {
                            for (int index = 0; index < mAreaArray.size(); index++) {
                                HashMap<String, String> match_param = new HashMap<String, String>();
                                match_param.put("keyword", mAreaArray.get(index).getName());

                                mHttp.sendRequest(
                                        IHttpRequest.RequestMethod.GET_METHOD,
                                        RemoteAPI.REQUEST_V1_HOME_AREA_DATA,
                                        null,
                                        match_param,
                                        RemoteAPICmd.REQUEST_V1_HOME_AREA_DATA_DISTRICT,
                                        AreaInfoController.class);
                            }
                        }
                    }
                    else{
                        //返回异常
                        Message message = new Message();
                        message.what = MSG_LOAD_AREA_ATTR;
                        sendMessageDelayed(message, 1000);
                    }
                }
                else if(actionId == RemoteAPICmd.REQUEST_V1_HOME_AREA_DATA_DISTRICT){
                    //Log.d(TAG, "onResponse: " + response);
                    ResponseInfo responseInfo = gson.fromJson(response, ResponseInfo.class);
                    if(responseInfo != null && responseInfo.getStatus() == 1) {
                        mLoadDistrictInfoNum += 1;
                        if (res.getJSONObject("data").has("area_data")) {
                            JSONArray data = res.getJSONObject("data").getJSONArray("area_data");
                            Type type = new TypeToken<List<DistrictInfo>>(){}.getType();
                            List<DistrictInfo> districtInfos = gson.fromJson(data.toString(), type);
                            for (int index = 0; index < districtInfos.size(); index++) {
                                for (int index2 = 0; index2 < mAreaArray.size(); index2++) {
                                    ProvinceInfo provinceInfo = mAreaArray.get(index2);
                                    if (districtInfos.get(index).getExtra().getProvince().getId().equals(provinceInfo.getId())) {
                                        List<CityInfo> cityInfos = provinceInfo.getCity();
                                        for (int index3 = 0; index3 < cityInfos.size(); index3++) {
                                            CityInfo cityInfo = cityInfos.get(index3);
                                            if (districtInfos.get(index).getExtra().getCity().getId().equals(cityInfo.getExtra().getCity().getId())) {
                                                cityInfo.addDistrict(districtInfos.get(index));
                                            }
                                        }
                                        break;
                                    }
                                }
                            }
                            //地址信息已经全部加载完毕
                            if(mLoadDistrictInfoNum == mAreaArray.size()){
                                mLoadAreaInfoStatus = EVENT_AREA_LOAD_DONE;
                                String areaInfo = gson.toJson(mAreaArray);
                                SharedPreferences sharedPreferences =
                                        DangerousCargoDriverApplication.getAppContext().getSharedPreferences("wsj_area",
                                                Context.MODE_PRIVATE);
                                SharedPreferences.Editor editor = sharedPreferences.edit();
                                editor.putString("area", areaInfo);
                                editor.commit();
                            }
                        }
                        else {

                        }
                    }
                    else{
                        //返回异常
                        Message message = new Message();
                        message.what = MSG_LOAD_AREA_ATTR;
                        sendMessageDelayed(message, 1000);
                    }
                }
                else{

                }
            }
            catch (JSONException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onErrorResponse(int actionId, String response) {
            if(actionId == RemoteAPICmd.REQUEST_V1_HOME_AREA_DATA_PROVINCE){
                //返回异常
                Message message = new Message();
                message.what = MSG_LOAD_AREA_ATTR;
                sendMessageDelayed(message, 1000);
            }
            else if(actionId == RemoteAPICmd.REQUEST_V1_HOME_AREA_DATA_CITY){
                //返回异常
                Message message = new Message();
                message.what = MSG_LOAD_AREA_ATTR;
                sendMessageDelayed(message, 1000);
            }
            else if(actionId == RemoteAPICmd.REQUEST_V1_HOME_AREA_DATA_DISTRICT){
                //返回异常
                Message message = new Message();
                message.what = MSG_LOAD_AREA_ATTR;
                sendMessageDelayed(message, 1000);
            }
            else{

            }
        }
    }
}
